/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "笔刷节点.h"

#include "../socket_utils.h"
#include "../../node后端.h"

#include "节点/节点树.h"

#include "../插座/C_数值插座.h"
#include "../插座/C_矢量插座.h"
#include "../插座/材质纹理插座.h"






C_笔刷节点::C_笔刷节点(S_设备环境& ctx) : C_节点基类(DEF_笔刷节点, E_节点类型::e_节点Type_并行) {
	f_setWName(u"纹理笔刷");
	m_Ctx = ctx;

	DEF_创建纹理插座_I(u"纹理", ctx);
	DEF_创建Vec2插座_I(u"坐标");
	DEF_创建Vec2插座_I(u"方向");
	DEF_创建F32插座_I(u"倾斜", nullptr);
	DEF_创建F32插座_I(u"压力", nullptr);
	DEF_创建F32插座_I(u"墨量", nullptr);

	DEF_创建纹理插座_O(u"纹理", ctx);


	m_线程调度方式 = f_alloc_EnumProp(nullptr, {
		{u""},
		{u""},
		}, u"调度方式");
	m_线程调度方式.m_私有 = true;


	m_笔刷类型 = f_alloc_EnumProp(nullptr, {
		{u"毛笔"},
		{u"铅笔"},
		{u"毛刷"},
		}, u"笔刷类型");
	m_笔刷类型.m_私有 = true;

	f_构建代码_构建GPU插座变量(*f_get输入插座(1));
	f_构建代码_构建GPU插座变量(*f_get输入插座(2));
	f_构建代码_构建GPU插座变量(*f_get输入插座(3));
	f_构建代码_构建GPU插座变量(*f_get输入插座(4));
	f_构建代码_构建GPU插座变量(*f_get输入插座(5));
	f_构建代码_构建GPU插座变量(*f_get输入插座(6));


}

C_笔刷节点::~C_笔刷节点() {
	f_prop_Release(m_线程调度方式);
	f_prop_Release(m_笔刷类型);

	f_构建代码_释放GPU插座变量(*f_get输入插座(1));
	f_构建代码_释放GPU插座变量(*f_get输入插座(2));
	f_构建代码_释放GPU插座变量(*f_get输入插座(3));
	f_构建代码_释放GPU插座变量(*f_get输入插座(4));
	f_构建代码_释放GPU插座变量(*f_get输入插座(5));
	f_构建代码_释放GPU插座变量(*f_get输入插座(6));
}

std::string C_笔刷节点::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	auto* socket4 = f_get输入插座(4);
	auto* socket5 = f_get输入插座(5);
	auto* socket6 = f_get输入插座(6);

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);
	m_Code += socket4->f_构建变量代码(0);
	m_Code += socket5->f_构建变量代码(0);
	m_Code += socket6->f_构建变量代码(0);

	socket1->f_upGPU块(0);
	socket2->f_upGPU块(0);
	socket3->f_upGPU块(0);
	socket4->f_upGPU块(0);
	socket5->f_upGPU块(0);
	socket6->f_upGPU块(0);
	//imageStore(writeLayers[nonuniformEXT(DEF_renderLayer_albedo)], iv, vec4(vec3(hitValue.Diffuse), 1)); gl_WorkGroupID.x
	auto 纹理 = socket1->f_getCode(0);

	auto rt = f_getThis节点树();
	switch (rt->m_树类型) {
		case E_节点树类型::e_type_并行节点树: {
			//m_Code += "imageStore(Ts[nonuniformEXT(" + 纹理 + ")], ivec2(" + socket2->f_getCode(0) + "), vec4(0.5, 1.0, 0, 1));\n";
			m_Code += "imageStore(Ts[nonuniformEXT(" + 纹理 + ")], ivec2(gl_WorkGroupID), vec4(0.5, 1.0, 0, 1));\n";
			break;
		}
		case E_节点树类型::e_type_着色节点树: {
			break;
		}
	}
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(纹理);
	if (m_区域父节点) {
		m_区域父节点->m_Code = m_Code;
		return "";
	}
	return m_Code;
}

void C_笔刷节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_0, S_引擎配置::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_线程调度方式, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_笔刷类型, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_笔刷节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_线程调度方式, 块);
	f_prop_Save(m_笔刷类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建笔刷节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_笔刷节点(ctx);
}

C_节点基类* f_node_加载笔刷节点(S_设备环境& ctx, FILE* f) {
	C_笔刷节点* node = new C_笔刷节点(ctx);
	return node;
}

void f_node_保存笔刷节点(C_节点基类* n, FILE* f) {
	C_笔刷节点* node = dynamic_cast<C_笔刷节点*>(n);
}






C_毛笔纹理笔刷节点::C_毛笔纹理笔刷节点(S_设备环境& ctx) : C_节点基类(DEF_毛笔纹理笔刷节点, E_节点类型::e_节点Type_并行) {
	f_setWName(u"纹理笔刷");
	m_Ctx = ctx;

	DEF_创建纹理插座_I(u"纹理", ctx);
	DEF_创建Vec2插座_I(u"坐标");
	DEF_创建Vec2插座_I(u"方向");
	DEF_创建F32插座_I(u"倾斜", nullptr);
	DEF_创建F32插座_I(u"压力", nullptr);
	DEF_创建F32插座_I(u"墨量", nullptr);

	DEF_创建F32插座_I(u"笔大小", nullptr);
	DEF_创建F32插座_I(u"毛半径", nullptr);

	DEF_创建纹理插座_O(u"纹理", ctx);


	m_清除 = f_alloc_BoolProp(nullptr, u"清除像素");
	m_清除.m_私有 = true;
	f_prop_Bool(m_清除) = true;

	m_填充颜色 = f_alloc_Vec4Prop(nullptr, u"填充颜色");
	m_填充颜色.m_私有 = true;
	f_prop_Vec4(m_填充颜色) = {0,0,0,1};

	m_线程调度方式 = f_alloc_EnumProp(nullptr, {
		{u""},
		{u""},
	}, u"调度方式");
	m_线程调度方式.m_私有 = true;

	m_笔刷类型 = f_alloc_EnumProp(nullptr, {
		{u"毛笔"},
		{u"铅笔"},
		{u"毛刷"},
		}, u"笔刷类型");
	m_笔刷类型.m_私有 = true;


	f_构建代码_构建GPU插座变量(*f_get输入插座(1));
	f_构建代码_构建GPU插座变量(*f_get输入插座(2));
	f_构建代码_构建GPU插座变量(*f_get输入插座(3));
	f_构建代码_构建GPU插座变量(*f_get输入插座(4));
	f_构建代码_构建GPU插座变量(*f_get输入插座(5));
	f_构建代码_构建GPU插座变量(*f_get输入插座(6));

	DEF_F32插座数据(f_get输入插座(4)) = 1.0;
	DEF_F32插座数据(f_get输入插座(5)) = 1.0;
	DEF_F32插座数据(f_get输入插座(6)) = 10.0;
	DEF_F32插座数据(f_get输入插座(7)) = 10.0;
	DEF_F32插座数据(f_get输入插座(8)) = 1.0;


	f_构建代码_分配渲染器GPU属性变量(m_填充颜色);
	

	m_参数 = {};
	f_df_allocGPU参数缓存槽(&m_参数, 2);

	//m_参数.m_参数槽[0] = f_scene_get纹理集(f_NodeCtx_get默认场景());
	//m_参数.m_参数类型[0] = E_板载缓存类型::e_IMAGE_Array;
	//m_参数.m_绑定位置[0] = DEF_TexturesBindID;
	//m_参数.m_绑定数量[0] = f_scene_get纹理集数量(f_NodeCtx_get默认场景());
	//
	m_参数.m_参数槽[0] = f_buf_getGlobal().m_全局绑定参数指针;
	m_参数.m_参数类型[0] = E_板载缓存类型::e_SSBO;
	m_参数.m_绑定位置[0] = DEF_BINDING_Render_GlobalParam;
	m_参数.m_绑定数量[0] = 1;

	//m_参数.m_纹理槽 = &S_全局缓存::g_全局模型纹理槽;
}

C_毛笔纹理笔刷节点::~C_毛笔纹理笔刷节点() {
	f_prop_Release(m_线程调度方式);
	f_prop_Release(m_笔刷类型);
	f_prop_Release(m_清除);
	f_prop_Release(m_填充颜色);

	f_构建代码_释放GPU插座变量(*f_get输入插座(1));
	f_构建代码_释放GPU插座变量(*f_get输入插座(2));
	f_构建代码_释放GPU插座变量(*f_get输入插座(3));
	f_构建代码_释放GPU插座变量(*f_get输入插座(4));
	f_构建代码_释放GPU插座变量(*f_get输入插座(5));
	f_构建代码_释放GPU插座变量(*f_get输入插座(6));
}

std::string C_毛笔纹理笔刷节点::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";
	auto name = f_getName();


	//C_插座基类* socket1;
	//C_插座基类* socket2;
	//C_插座基类* socket3;
	//C_插座基类* socket4;
	//C_插座基类* socket5;
	//C_插座基类* socket6;
	//C_插座基类* socket7;

	bool 数组 = false;
	auto rt = f_getThis节点树();
	switch (rt->m_树类型) {
		case E_节点树类型::e_type_并行节点树: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec2);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 3, E_值类型::e_Type_Vec2);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 4, E_值类型::e_Type_F32);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 5, E_值类型::e_Type_F32);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 6, E_值类型::e_Type_F32);
			break;
		}
		default: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec2_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 3, E_值类型::e_Type_Vec2_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 4, E_值类型::e_Type_F32_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 5, E_值类型::e_Type_F32_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 6, E_值类型::e_Type_F32_1D);
			数组 = true;
		}
	}

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	auto* socket4 = f_get输入插座(4);
	auto* socket5 = f_get输入插座(5);
	auto* socket6 = f_get输入插座(6);
	auto* socket7 = f_get输入插座(7);
	auto* socket8 = f_get输入插座(8);

	

	socket2->m_传至GPU = true;
	socket3->m_传至GPU = true;
	socket4->m_传至GPU = true;
	socket5->m_传至GPU = true;
	socket6->m_传至GPU = true;
	//socket7->m_传至GPU = true;

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);
	m_Code += socket4->f_构建变量代码(0);
	m_Code += socket5->f_构建变量代码(0);
	m_Code += socket6->f_构建变量代码(0);
	m_Code += socket7->f_构建变量代码(0);
	m_Code += socket8->f_构建变量代码(0);

	m_Code += "{\n";
	socket1->f_upGPU块(0);
	socket2->f_upGPU块(0);
	socket3->f_upGPU块(0);
	socket4->f_upGPU块(0);
	socket5->f_upGPU块(0);
	socket6->f_upGPU块(0);
	
	//imageStore(writeLayers[nonuniformEXT(DEF_renderLayer_albedo)], iv, vec4(vec3(hitValue.Diffuse), 1)); gl_WorkGroupID.x
	auto 纹理 = socket1->f_getCode(0);
	auto 坐标 = socket2->f_getCode(0, 数组);
	auto 方向 = socket3->f_getCode(0, 数组);
	auto 倾斜 = socket4->f_getCode(0, 数组);
	auto 压力 = socket5->f_getCode(0, 数组);
	auto 墨量 = socket6->f_getCode(0, 数组);
	auto 大小 = socket7->f_getCode(0, 数组);
	auto 半径 = socket8->f_getCode(0);
	

	
	switch (rt->m_树类型) {
		case E_节点树类型::e_type_并行节点树: {
			
			m_Code += "uint h = uint(float(gl_WorkGroupSize.x) * length(" + 方向 + ") * " + 倾斜 + " );\n";
			m_Code += "for(uint x=0; x<h; ++x){\n";
			//m_Code += "float a = f_ellipse(vec2(x, gl_LocalInvocationIndex) / vec2(h, gl_WorkGroupSize.y), vec2(0.5), vec2(0.0, 0.0), vec2(0.3745*0.5, 1*0.5));\n";
			m_Code += "float a = f_ellipse(vec2(x, gl_LocalInvocationIndex) / vec2(h, gl_WorkGroupSize.x), vec2(0.5), vec2(0.0, 0.0), vec2(1, 1));\n";
			
			m_Code += "vec2 spiralCoord = generate_point(int(gl_WorkGroupID.y), int(gl_NumWorkGroups.y), 10, 5) ;\n";
			//m_Code += "spiralCoord = (1 - length(spiralCoord)) / gl_WorkGroupSize.x ;\n";
			m_Code += "spiralCoord *= " + 压力 + ";\n";
			//m_Code += "vec2 spiralCoord = generate_point(int(gl_WorkGroupID.y), 0.1);\n"; " * " + 半径 +  + 方向
			m_Code += "spiralCoord += f_rotDir(vec2(x, gl_LocalInvocationIndex), " + 方向 + ");\n";
			m_Code += "spiralCoord += ivec2(" + 坐标 + ");\n";
			//m_Code += "ivec2 textureSize = imageSize(Ts[nonuniformEXT(" + 纹理 + ")]);\n";
			m_Code += "vec4 color = vec4(0, min((0.5-a),1), 0, 1);\n";

			m_Code += "ivec2 offset = ivec2(spiralCoord);\n";
			m_Code += "imageAtomicAdd(Ts[nonuniformEXT(" + 纹理 + ")], offset, color.g*" + 墨量 + ");\n";
			
			m_Code += "};\n";
			break;
		}
		case E_节点树类型::e_type_着色节点树: {
			break;
		}
		default: {
			auto* rt = f_getThis节点树();

			if (f_prop_Bool(m_清除)) {
				m_Code += "{\n";

				auto 填充颜色 = f_代码构建_属性变量(m_填充颜色, rt);

				auto 单色笔刷常量名称 = "单色笔刷_" + name;
				m_Code += DEF_S(S_Brush_Monochrome)" " + 单色笔刷常量名称 + ";\n";
				m_Code += 单色笔刷常量名称 + ".texID = " + DEF_S(f_JIT_getGPU纹理ID)"(" + 纹理 + ");\n";
				m_Code += 单色笔刷常量名称 + ".colorA = " + 填充颜色 + ";\n";
				m_Code += 单色笔刷常量名称 + ".colorB = " + 填充颜色 + ";\n";

				m_Code += DEF_S(f_JIT_upGPU纹理笔刷参数)"((S_GPU计算*)" + DEF_指针转字符串(S_节点数据::g单色纹理笔刷_计算环境);
				m_Code += ", ((S_GPU参数槽*)" + DEF_指针转字符串(&m_参数) + ") );\n";

				m_Code += DEF_S(uvec3)" 维度 = ";
				m_Code += DEF_S(f_tex_分辨率)"(" + 纹理 + ");\n";
				m_Code += DEF_S(f_GPU_run计算)"((S_GPU计算*)" + DEF_指针转字符串(S_节点数据::g单色纹理笔刷_计算环境) + ", 维度, &" + 单色笔刷常量名称 + ", sizeof(S_Brush_Monochrome), 0);\n";

				m_Code += "}\n";
			}
			


			auto 常量名称 = "ConstPush_" + name;
			m_Code += DEF_S(S_Brush_Maobi)" " + 常量名称 + ";\n";

			m_Code += 常量名称 + ".texID = " + DEF_S(f_JIT_getGPU纹理ID)"(" + 纹理 + ");\n";
			m_Code += 常量名称 + ".point = " + 坐标 + ".m_Mem.m_偏移;\n";
			m_Code += 常量名称 + ".dir = " + 方向 + ".m_Mem.m_偏移;\n";
			m_Code += 常量名称 + ".tilt = " + 倾斜 + ".m_Mem.m_偏移;\n";
			m_Code += 常量名称 + ".pressure = " + 压力 + ".m_Mem.m_偏移;\n";
			m_Code += 常量名称 + ".ink = " + 墨量 + ".m_Mem.m_偏移;\n";
			m_Code += 常量名称 + ".radius = " + 半径 + ";\n";

			m_Code += DEF_S(f_JIT_upGPU纹理笔刷参数)"((S_GPU计算*)" + DEF_指针转字符串(S_节点数据::g毛笔笔刷_计算环境);
			m_Code += ", ((S_GPU参数槽*)" + DEF_指针转字符串(&m_参数) + ") );\n";

			m_Code += DEF_S(uvec3)" 维度 = {1,1,1};";
			m_Code += "维度.x = ";
			m_Code += DEF_S(DEF_Max)"((" + socket2->f_getCode(0, false) + ")->count, 维度.x);\n";
			m_Code += "维度.x = ";
			m_Code += DEF_S(DEF_Max)"((" + socket3->f_getCode(0, false) + ")->count, 维度.x);\n";
			m_Code += "维度.x = ";
			m_Code += DEF_S(DEF_Max)"((" + socket4->f_getCode(0, false) + ")->count, 维度.x);\n";
			m_Code += "维度.x = ";
			m_Code += DEF_S(DEF_Max)"((" + socket5->f_getCode(0, false) + ")->count, 维度.x);\n";
			m_Code += "维度.x = ";
			m_Code += DEF_S(DEF_Max)"((" + socket6->f_getCode(0, false) + ")->count, 维度.x);\n";
			
			m_Code += "维度.y = ";
			m_Code += DEF_S(DEF_Min)"(" + socket7->f_getCode(0, false) + ", 4096);\n";
			m_Code += "维度.z = ";
			m_Code += DEF_S(DEF_Min)"(" + socket8->f_getCode(0, false) + ", 64);\n";

			m_Code += DEF_S(f_GPU_run计算)"((S_GPU计算*)" + DEF_指针转字符串(S_节点数据::g毛笔笔刷_计算环境) + ", 维度, &" + 常量名称 + ", sizeof(S_Brush_Maobi), 0);\n";

			m_Code += m_ReleaseCode;
			break;
		}
	}
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(纹理);
	if (m_区域父节点) {
		m_区域父节点->m_Code = m_Code;
		return "";
	}
	return m_Code;
}

void C_毛笔纹理笔刷节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_17, S_引擎配置::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_清除, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_填充颜色, 下一次读取数据指针);
		}
		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_0, S_引擎配置::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_线程调度方式, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_笔刷类型, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_毛笔纹理笔刷节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_清除, 块);
	f_prop_Save(m_填充颜色, 块);
	f_prop_Save(m_线程调度方式, 块);
	f_prop_Save(m_笔刷类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建毛笔纹理笔刷节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_毛笔纹理笔刷节点(ctx);
}

C_节点基类* f_node_加载毛笔纹理笔刷节点(S_设备环境& ctx, FILE* f) {
	C_毛笔纹理笔刷节点* node = new C_毛笔纹理笔刷节点(ctx);
	return node;
}

void f_node_保存毛笔纹理笔刷节点(C_节点基类* n, FILE* f) {
	C_毛笔纹理笔刷节点* node = dynamic_cast<C_毛笔纹理笔刷节点*>(n);
}








C_设置纹理像素节点::C_设置纹理像素节点(S_设备环境& ctx) : C_节点基类(DEF_设置纹理像素节点, E_节点类型::e_节点Type_并行) {
	f_setWName(u"纹理笔刷");
	m_Ctx = ctx;

	DEF_创建纹理插座_I(u"纹理", ctx);
	DEF_创建iVec2插座_I(u"坐标");
	DEF_创建Vec4插座_I(u"颜色");

	DEF_创建纹理插座_O(u"纹理", ctx);


	m_叠加类型 = f_alloc_EnumProp(nullptr, {
		{u"替换"},
		{u"添加"},
		{u"相减"},
		{u"相乘"},
		}, u"调度方式");
	m_叠加类型.m_私有 = true;


	f_构建代码_构建GPU插座变量(*f_get输入插座(1));
	f_构建代码_构建GPU插座变量(*f_get输入插座(2));
	f_构建代码_构建GPU插座变量(*f_get输入插座(3));

}

C_设置纹理像素节点::~C_设置纹理像素节点() {
	f_prop_Release(m_叠加类型);

	f_构建代码_释放GPU插座变量(*f_get输入插座(1));
	f_构建代码_释放GPU插座变量(*f_get输入插座(2));
	f_构建代码_释放GPU插座变量(*f_get输入插座(3));
}

std::string C_设置纹理像素节点::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	socket1->f_upGPU块(0);
	socket2->f_upGPU块(0);
	socket3->f_upGPU块(0);
	
	auto 纹理 = socket1->f_getCode(0);

	auto rt = f_getThis节点树();
	switch (rt->m_树类型) {
		case E_节点树类型::e_type_并行节点树: {
			
			m_Code += "{\n";

			m_Code += "ivec2 Coord = ivec2(" + socket2->f_getCode(0) + ");\n";
			m_Code += "vec4 Color = vec4(" + socket3->f_getCode(0) + ");\n";

			m_Code += "imageStore(Ts[nonuniformEXT(" + 纹理 + ")], Coord, Color);\n";
			//m_Code += "imageStore(Ts[nonuniformEXT(" + 纹理 + ")], Coord, ivec4(floatBitsToInt(0)));\n";
			//m_Code += "imageStore(Ts[nonuniformEXT(" + 纹理 + ")], Coord, vec4(0));\n";
			//m_Code += "imageStore(Ts[nonuniformEXT(" + 纹理 + ")], 1, 0);\n";

			m_Code += "}\n";

			break;
		}
		case E_节点树类型::e_type_着色节点树: {
			break;
		}
	}
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(纹理);
	if (m_区域父节点) {
		m_区域父节点->m_Code = m_Code;
		return "";
	}
	return m_Code;
}

void C_设置纹理像素节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_0, S_引擎配置::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_叠加类型, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_设置纹理像素节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_叠加类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建设置纹理像素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置纹理像素节点(ctx);
}

C_节点基类* f_node_加载设置纹理像素节点(S_设备环境& ctx, FILE* f) {
	C_设置纹理像素节点* node = new C_设置纹理像素节点(ctx);
	return node;
}

void f_node_保存设置纹理像素节点(C_节点基类* n, FILE* f) {
	C_设置纹理像素节点* node = dynamic_cast<C_设置纹理像素节点*>(n);
}


